import { parseHTML } from "./parse";
function genProps(attrs) {
  let str = '';
  for(let i = 0; i < attrs.length; i++) {
    let attr = attrs[i];
    if(attr.name === 'style') {
      let obj = {}
      attr.value.split(';').forEach(item => {
        let [key, value] = item.split(':');
        obj[key] = value;
      });
      attr.value = obj;
    }
    str += `${attr.name}:${JSON.stringify(attr.value)},`
  }
  return `{${str.slice(0, -1)}}`
}
function genChildren(children) {
  return children.map(child => gen(child)).join(',')
}
const defaultTagRE = /\{\{((?:.|\r?\n)+?)\}\}/g
function gen(node) {
  if(node.type === 1) {
    return codegen(node);
  }else {
    let text = node.text
    if(!defaultTagRE.test(text)) {
      return `_v(${JSON.stringify(text)})`
    }else {
      let tokens = [];
      let match;
      defaultTagRE.lastIndex = 0;
      let lastIndex = 0;
      while(match = defaultTagRE.exec(text)) {
        let index = match.index;
        if(index > lastIndex) {
          tokens.push(JSON.stringify(text.slice(lastIndex, index)))
        }
        tokens.push(`_s(${match[1].trim()})`)
        lastIndex = index + match[0].length
      }
      if(lastIndex < text.length) {
        tokens.push(JSON.stringify(text.slice(lastIndex)))
      }
      return `_v(${tokens.join('+')})`
    }
  }

}
//拼接字符串，用于render函数
function codegen(ast) {
  let children = genChildren(ast.children);
  let code = `_c('${ast.tag}',${ast.attrs.length > 0 ? genProps(ast.attrs) : 'null'}${ast.children.length?`,${children}`:''})`
  return code;
}
// 这是个模板编译文件 redner方法把模板编译成函数
export function compilToFunction(template) {
  // 步骤：
  //  1.就是将template 转化为 ast 语法树
  //  2.生成render方法 （render方法执行后的结果就是 虚拟DOM）
  let ast = parseHTML(template) //ast代表树结构

  //根据ast生成一定的格式，简单来说就是拼接字符串
  let code = codegen(ast);
  code = `with(this){return ${code}}`;
  let render = new Function(code);
  return render;
}